parser grammar YACCParser;

options {
  language = Java;
  tokenVocab = YACCLexer;
}

@rulecatch {catch (RecognitionException e) {
  throw e;}
 }
 
@header {
package PL.prac7;
}

entrada: definiciones expresiones partec? EOF;

identificador: IDENT(ACORCHETE (operacion)? CCORCHETE)?;
struct: (ASTERISCO? identificador|VAR|DOLARDOLAR|llamada_funcion) (PUNTO IDENT)?;
subsentencia: (struct| NUMERO | CADENA | CARACTER);
operacion: MENOS? subsentencia ((MAS|MENOS|ASTERISCO|BARRA) MENOS? subsentencia)*;
igualacion: struct (IGUAL operacion)*;
sentencia: igualacion (COMA igualacion)* SEPARADOR;
definicion: (TIPO|IDENT) igualacion (COMA igualacion)* SEPARADOR;



definiciones: INIDEFINICIONES declaracionc FINDEFINICIONES (definiciontoken)*; 
declaracionc: (define| include|typedefs|declarfunc|array)+;
array: (IDENT|TIPO) IDENT ACORCHETE NUMERO CCORCHETE SEPARADOR;
declarfunc: (TIPO|IDENT) llamada_funcion (COMA llamada_funcion)* SEPARADOR;
typedefs: TYPEDEF STRUCT IDENT ALLAVE (varindefs)+ CLLAVE IDENT SEPARADOR;
varindefs: (TIPO|IDENT) IDENT (COMA IDENT)* SEPARADOR;
definiciontoken: PORCENTAJE IDENT (IDENT|(CARACTER)+|conjunto|(MENOR IDENT MAYOR IDENT+));
typetoken: PORCENTAJE (TYPE|TOKEN) MENOR IDENT MAYOR IDENT+;
conjunto: ALLAVE (varindefs)+ CLLAVE;
define: ALMOHADILLA DEFINE IDENT (TIPO|NUMERO);
include: ALMOHADILLA INCLUDE MENOR IDENT PUNTO IDENT MAYOR;


expresiones: ZONAREGLA reglas* ZONAREGLA;
reglas: IDENT DOSPUNTOS patron? (ORYACC patron)* SEPARADOR;
patron: (CARACTER| PORCENTAJE? IDENT)+ def_cuerpo?;
llamada_funcion: IDENT APARENTESIS (operacion)? (segundo_param)* CPARENTESIS;
segundo_param: COMA (operacion) ;


partec: declaracionc? declaracion* funcion+;
declaracion: EXTERN IDENT ASTERISCO? IDENT SEPARADOR;

funcion: def_funcion def_cuerpo;
def_funcion: (TIPO|VOID|IDENT)? (IDENT|MAIN) APARENTESIS (VOID | ((llamada_variable| IDENT) (COMA (llamada_variable | IDENT))*)?) CPARENTESIS definicion*;
llamada_variable: TIPO (ASTERISCO)* IDENT (ACORCHETE CCORCHETE)?;

def_cuerpo: ALLAVE (sentencia|definicion|retorno|bucles)* CLLAVE;
retorno: RETURN (APARENTESIS subsentencia CPARENTESIS | subsentencia) SEPARADOR;

comparacion:APARENTESIS reglascond ((AND | OR) reglascond)* CPARENTESIS;
igualarencond: APARENTESIS operacion (IGUAL operacion)? CPARENTESIS| operacion;
reglascond:NOT?(( igualarencond ((MAYOR IGUAL?|MENOR IGUAL?| IGUAL IGUAL) igualarencond)?) |cond_aritmetico| IDENT MAS MAS);
bucle: WHILE comparacion;  
buclefor: FOR comparacion_for;
comparacion_for: APARENTESIS comparacion1? SEPARADOR comparacion2? SEPARADOR comparacion3? CPARENTESIS;
comparacion1: (TIPO)? IDENT IGUAL NUMERO;
infor: APARENTESIS operacion CPARENTESIS;
comparacion2: (infor|struct) (MAYOR IGUAL?|MENOR IGUAL?| IGUAL IGUAL) (NUMERO|IDENT);
comparacion3: (IDENT (MAS MAS| MENOS MENOS) | (MAS MAS | MENOS MENOS) IDENT) (COMA igualacion)?;
estructuracond: IF comparacion cuerpobucles (ELSE cuerpobucles)?;
bucles: (((bucle|buclefor) cuerpobucles )| estructuracond );
cuerpobucles: (ALLAVE cuerpo* CLLAVE |cuerpo);
cuerpo: (bucles|definicion|sentencia|retorno|BREAK SEPARADOR);

cond_aritmetico: IDENT (MAYOR IGUAL?|MENOR IGUAL?| IGUAL IGUAL) NUMERO INTERROGANTE NUMERO DOSPUNTOS NUMERO;
